﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using CMISLibrary.Entities;
using CMISLibrary;
using BCNPCObject.DB;

namespace BCNPCObject
{
    public class cls_NPC_INTOGCS_DNGUON_Controller
    {
        //Lấy thông tin tờ ghi chỉ số công tơ cơ  - mẫu chung NPC
        public DataSet TogcsNPC_Co(Int16 i16NamHD, Int16 i16ThangHD, Int16 i16Ky, string strMa_dviqly, string strMa_sogcs, string strMa_khang, string strLoaiCto, ref string strErr)
        {
            try
            {
                var qddosogcs = (from p in CMIS2.DB.TT_DDO_SOGCS
                                 where p.MA_DVIQLY == strMa_dviqly
                                 && p.MA_SOGCS == strMa_sogcs
                                 //&& p.NGAY_HLUC == CMIS2.DB.TT_DDO_SOGCS.Where(c=> c.MA_DDO == p.MA_DDO).Max(c2=> c2.NGAY_HLUC)
                                 select new
                                 {
                                     p.MA_DVIQLY, // = pgroup.Key.MA_DVIQLY,
                                     p.MA_DDO,  // = pgroup.Key.MA_DDO,
                                     p.MA_SOGCS,  // = pgroup.Key.MA_SOGCS,
                                     p.STT,
                                     p.NGAY_HLUC,
                                     p.ID_QHE
                                 }).ToList();
                if (qddosogcs.Count < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                string[] ArrDDO = qddosogcs.Select(c => c.MA_DDO).Distinct().ToArray();

                var DDOinTT_DDO_SOGCS = (from p in CMIS2.DB.TT_DDO_SOGCS
                                         where p.MA_DVIQLY == strMa_dviqly
                                         && ArrDDO.Contains(p.MA_DDO)
                                         select p).ToList();

                var DDOMaxHL = (DDOinTT_DDO_SOGCS.Where(c => c.NGAY_HLUC == DDOinTT_DDO_SOGCS.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC))).ToList();

                //danh sach diem do hien tai thuoc so                               
                var DDDOSOGCS = (from p in DDOMaxHL
                                 where p.MA_SOGCS == strMa_sogcs
                                 select p).ToList();

                string[] ArrDDOSOGCS = DDDOSOGCS.Select(c => c.MA_DDO).Distinct().ToArray();

                List<TT_CHISO> GCS1 = new List<TT_CHISO>();

                // Lấy ra những điểm đo còn treo công tơ và treo công tơ cơ
                if (strLoaiCto == "CoDN")
                {
                    GCS1 = LayTTin_ChiSo_Co(strMa_dviqly, ArrDDOSOGCS);
                }
                else
                {
                    return null;
                }

                // Mảng diem do hien tai thuoc so và là điểm đo treo công tơ cơ
                string[] ArrDDOSOGCS_Co = GCS1.Select(c => c.MA_DDO).Distinct().ToArray();



                //danh sach diem do hien tai thuoc so và treo công tơ cơ
                var DDOSOGCSfin = (from p in DDDOSOGCS
                                   where p.MA_SOGCS == strMa_sogcs
                                   && ArrDDOSOGCS_Co.Contains(p.MA_DDO)
                                   select p).ToList();




                string[] ArrMADDO = DDOSOGCSfin.Select(c => c.MA_DDO).Distinct().ToArray();

                if (ArrMADDO.Count() < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                //var nl = ArrMADDO.AsEnumerable();

                var DIEMDO = (from p in CMIS2.DB.TT_DIEM_DO
                              where p.MA_DVIQLY == strMa_dviqly
                              && ArrMADDO.Contains(p.MA_DDO)
                              select new
                              {
                                  p.MA_DVIQLY,
                                  p.MA_DDO,
                                  MA_CAPDA = "0" + p.MA_CAPDA,
                                  p.ID_DIA_CHINH,
                                  p.CSUAT,
                                  p.SO_PHA,
                                  p.LAN_CAPNHAT,
                                  p.THAO_TACCDL,
                                  p.NGAY_HLUC,
                                  p.MO_TA,
                                  p.TRANG_THAI,
                                  p.TTRANG_TREOTHAO,
                                  p.TEN_DDO
                              }).ToList();

                if (DIEMDO.Count() < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                var DIEMDOMaxHL1 = (DIEMDO.Where(c => c.NGAY_HLUC == DIEMDO.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC) && c.TRANG_THAI == 1)).ToList();

                var DIEMDOMaxHL = (DIEMDOMaxHL1.Where(c => c.LAN_CAPNHAT == DIEMDOMaxHL1.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.LAN_CAPNHAT))).ToList();
                if (DIEMDOMaxHL.Count < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                // Lấy cấp Điện áp của điểm đo
                var CAPDAP = (from p in DIEMDOMaxHL
                              join m in CMIS2.DB.D_CAP_DAP
                              on new { p.MA_CAPDA } equals new { m.MA_CAPDA }
                              select new
                              {
                                  p.MA_DDO,
                                  m.TEN_CAPDA
                              }).ToList();



                var VTDDO = (from p in CMIS2.DB.TT_VITRI_DDO
                             where p.MA_DVIQLY == strMa_dviqly
                             && ArrMADDO.Contains(p.MA_DDO)
                             select p).ToList();

                var VTDDOMaxHL = (VTDDO.Where(c => c.NGAY_HLUC == VTDDO.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC))).ToList();
                if (VTDDOMaxHL.Count() < 1) { strErr = "Không lấy được vị trí điểm đo"; return null; }

                string[] ArrTRAM = VTDDOMaxHL.Select(c => c.MA_TRAM).Distinct().ToArray();
                string[] ArrLO = VTDDOMaxHL.Select(c => c.MA_LO).Distinct().ToArray();
                string[] ArrTO = VTDDOMaxHL.Select(c => c.MA_TO).Distinct().ToArray();

                var TRAM = (from p in CMIS2.DB.D_TRAM
                            where p.MA_DVIQLY == strMa_dviqly
                            && ArrTRAM.Contains(p.MA_TRAM)
                            select p).ToList();
                if (TRAM.Count() < 1) { strErr = "Không lấy được danh sách trạm"; }

                var LO = (from p in CMIS2.DB.D_LO
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrLO.Contains(p.MA_LO)
                          select p).ToList();
                if (LO.Count() < 1) { strErr = "Không lấy được danh sách lộ"; }

                var TO = (from p in CMIS2.DB.D_TO
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrTO.Contains(p.MA_TO)
                          select p).ToList();
                if (TO.Count() < 1) { strErr = "Không lấy được danh sách tổ"; }


                var joi1 = (from p in DDOSOGCSfin.ToList()
                            join m in DIEMDOMaxHL.ToList()
                            on new { p.MA_DDO } equals new { m.MA_DDO }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                m.SO_PHA,
                                m.CSUAT,
                                m.TEN_DDO
                            }).ToList();

                //string[] ArrMAKHANG = joi1.Select(c => c.MA_KHANG).Distinct().ToArray();
                //if (ArrMAKHANG.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //var KHACHHANG = (from p in CMIS2.DB.HDG_KHACH_HANG
                //                 where p.MA_DVIQLY == strMa_dviqly
                //                 && ArrMAKHANG.Contains(p.MA_KHANG)
                //                 select p).ToList();
                //if (KHACHHANG.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //var KHACHHANGMaxHL = (KHACHHANG.Where(c => c.NGAY_HLUC == KHACHHANG.Where(c2 => c2.MA_KHANG == c.MA_KHANG).Max(c3 => c3.NGAY_HLUC) && c.TRANG_THAI == 1)).ToList();
                //if (KHACHHANGMaxHL.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //long[] ArrIDHDONG = KHACHHANGMaxHL.Select(c => c.ID_HDONG).ToArray();

                //var HOPDONG = (from p in CMIS2.DB.HDG_HOP_DONG
                //               where p.MA_DVIQLY == strMa_dviqly
                //               && ArrIDHDONG.Contains(p.ID_HDONG)
                //               select p).ToList();

                //var HOPDONGMaxHL = (HOPDONG.Where(c => c.NGAY_HLUC == HOPDONG.Where(a => a.ID_HDONG == c.ID_HDONG).Max(s => s.NGAY_HLUC))).ToList();
                //if (HOPDONGMaxHL.Count() < 1) { strErr = "Không lấy được thông tin hợp đồng"; return null; }

                var joi2 = (from p in joi1
                            //join m in KHACHHANGMaxHL
                            //on new { p.MA_KHANG } equals new { m.MA_KHANG }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.SO_PHA,
                                p.CSUAT,
                                p.TEN_DDO
                            }).ToList();


                var joi3 = (from p in joi2
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.SO_PHA,
                                p.CSUAT,
                                p.TEN_DDO
                            }).ToList();


                List<TT_CHISO> GCS = new List<TT_CHISO>();

                if (strLoaiCto == "CoDN")
                {
                    GCS = LayTTin_ChiSo_Co(strMa_dviqly, ArrMADDO);
                }
                else
                {
                    return null;
                }

                if (GCS.Count() < 1) { strErr = "Không lấy được chỉ số"; return null; }



                var joi4 = (from p in joi3
                            join m in GCS
                            on new { p.MA_DDO } equals new { m.MA_DDO }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.TEN_DDO,
                                p.SO_PHA,
                                p.CSUAT,
                                m.KY,
                                m.THANG,
                                m.NAM,
                                m.CHISO_MOI,
                                m.CHISO_CU,
                                m.LOAI_CHISO,
                                m.BCS,
                                m.HS_NHAN,
                                m.MA_CTO,
                                m.SO_CTO,
                                m.MA_CNANG
                            }).ToList();


                string[] ArrMACTO = GCS.Select(c => c.MA_CTO).Distinct().ToArray();

                var CTO = (from p in CMIS2.DB.DD_HOSO_CTO
                           where p.MA_DVIQLY == strMa_dviqly
                           && ArrMACTO.Contains(p.MA_CTO)
                           select p).ToList();
                if (CTO.Count() < 1) { strErr = "Không lấy được thông tin công tơ"; return null; }

                string[] CLOAI = CTO.Select(c => c.MA_CLOAI).Distinct().ToArray();


                var D_CLOAI_CTO = (from p in CMIS2.DB.D_CLOAI_CTO
                                   where CLOAI.Contains(p.MA_CLOAI)
                                   select new { p.MA_CLOAI, p.SO_PHA, p.MA_NUOC, p.SO_CSO, p.DONG_DIEN, p.HANGSO_K }).ToList();

                var CLOAICTO = (from p in CTO
                                select new
                                {
                                    p.MA_DVIQLY,
                                    p.MA_CTO,
                                    SO_PHA = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.SO_PHA).FirstOrDefault(),
                                    MA_NUOC = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.MA_NUOC).FirstOrDefault(),
                                    SO_CSO = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.SO_CSO).FirstOrDefault(),
                                    DONG_DIEN = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.DONG_DIEN).FirstOrDefault(),
                                    HANGSO_K = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.HANGSO_K).FirstOrDefault()
                                }).ToList();

                var KDINH = (from p in CMIS2.DB.DD_KDINH_CTO
                             where p.MA_DVIQLY == strMa_dviqly
                             && ArrMACTO.Contains(p.MA_CTO)
                             select p).ToList();

                var BDONGHTAI_CTO = (from p in CMIS2.DB.DD_BDONG_HTAI
                                     where p.MA_DVIQLY == strMa_dviqly
                                     && ArrMACTO.Contains(p.MA_TBI)
                                     select new
                                     {
                                         MA_CTO = p.MA_TBI,
                                         p.NGAY_BDONG
                                     }).ToList();


                var KDINHMaxHL = (KDINH.Where(c => c.ID_BBAN_KDINH == KDINH.Where(c2 => c2.MA_CTO == c.MA_CTO).Max(c3 => c3.ID_BBAN_KDINH))).ToList();

                // lay han kiem dinh
                var KDINHMaxHLjoiCLOAICTO = (from p in KDINHMaxHL
                                             join m in CLOAICTO
                                             on new { p.MA_CTO } equals new { m.MA_CTO }
                                             select new
                                             {
                                                 p.MA_CTO,
                                                 m.SO_PHA,
                                                 m.MA_NUOC,
                                                 m.SO_CSO,
                                                 m.DONG_DIEN,
                                                 m.HANGSO_K,
                                                 NGAY_KDINH = p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.ToString("dd/MM/yyyy"),
                                                 HAN_KDINH = m.SO_PHA.ToString() == "1" ? (p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.AddYears(5).ToString("dd/MM/yyyy")) : (p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.AddYears(2).ToString("dd/MM/yyyy"))
                                             }).ToList();

                var HANKDINH = (from p in KDINHMaxHLjoiCLOAICTO
                                join m in BDONGHTAI_CTO
                                on new { p.MA_CTO } equals new { m.MA_CTO }
                                select new
                                {
                                    p.MA_CTO,
                                    p.SO_PHA,
                                    p.MA_NUOC,
                                    p.SO_CSO,
                                    p.DONG_DIEN,
                                    HANGSO_K = p.HANGSO_K,
                                    p.NGAY_KDINH,
                                    p.HAN_KDINH,
                                    NGAY_BDONG = m.NGAY_BDONG.Date.ToString("dd/MM/yyyy")
                                }).ToList();

                // lấy TU trong DD_BDONG_HTAI
                var TU = (from p in CMIS2.DB.DD_BDONG_TU
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrMADDO.Contains(p.MA_DDO)
                          select p).ToList();

                var TUmaxID = (TU.Where(c => c.ID_BBAN == TU.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.ID_BBAN) && c.MA_BDONG == "B")).ToList();

                var TUKdinh = (from p in TUmaxID
                               join m in CMIS2.DB.DD_KDINH_TU
                              on new { p.MA_DVIQLY, p.MA_TU } equals new { m.MA_DVIQLY, m.MA_TU }
                               select new
                               {
                                   p.MA_DDO,
                                   p.MA_TU,
                                   m.NGAY_KDINH
                               }).ToList();

                // Không đúng
                //var TUKdinh = (from p in CMIS2.DB.DD_KDINH_TU
                //               join m in TUmaxID
                //              on new { p.MA_DVIQLY, p.MA_TU } equals new { m.MA_DVIQLY, m.MA_TU }
                //               select new
                //               {
                //                   m.MA_DDO,
                //                   m.MA_TU,
                //                   p.NGAY_KDINH
                //               }).ToList();


                // lấy TI trong DD_BDONG_HTAI
                var TI = (from p in CMIS2.DB.DD_BDONG_TI
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrMADDO.Contains(p.MA_DDO)
                          select p).ToList();

                var TImaxID = (TI.Where(c => c.ID_BBAN == TI.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.ID_BBAN) && c.MA_BDONG == "B")).ToList();

                var TIKdinh = (from p in TImaxID
                               join m in CMIS2.DB.DD_KDINH_TI
                              on new { p.MA_DVIQLY, p.MA_TI } equals new { m.MA_DVIQLY, m.MA_TI }
                               select new
                               {
                                   p.MA_DDO,
                                   p.MA_TI,
                                   m.NGAY_KDINH
                               }).ToList();


                var joi5 = (from p in joi4
                            join m in VTDDOMaxHL
                            on new { p.MA_DDO } equals new { m.MA_DDO }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.TEN_DDO,
                                p.KY,
                                p.THANG,
                                p.NAM,
                                p.CHISO_MOI,
                                p.CHISO_CU,
                                p.LOAI_CHISO,
                                p.BCS,
                                p.HS_NHAN,
                                p.MA_CTO,
                                p.SO_CTO,
                                p.SO_PHA,
                                p.CSUAT,
                                p.MA_CNANG,
                                m.MA_LO,
                                m.MA_TO,
                                m.MA_TRAM,
                            }).ToList();



                var joi7 = (from p in joi5
                            join m in CTO
                            on new { p.MA_DVIQLY, p.MA_CTO } equals new { m.MA_DVIQLY, m.MA_CTO }
                            orderby p.STT
                            select new
                            {
                                CHON = false,
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                DIA_CHI = p.TEN_DDO,
                                KY = p.KY.ToString(),
                                THANG = p.THANG.ToString(),
                                NAM = p.NAM.ToString(),
                                p.CHISO_MOI,
                                p.CHISO_CU,
                                p.LOAI_CHISO,
                                p.BCS,
                                p.HS_NHAN,
                                p.MA_CTO,
                                p.SO_CTO,
                                p.MA_LO,
                                p.MA_TO,
                                p.MA_TRAM,
                                PHA = p.SO_PHA.ToString(),
                                CSUAT_DDO = p.CSUAT.ToString(),
                                HSN = p.HS_NHAN,
                                p.MA_CNANG,
                                m.MA_CLOAI,
                                m.NAM_SX,
                                m.LOAI_SOHUU,
                                NGAY_BDONG = m.NGAY_BDONG == null ? null : m.NGAY_BDONG.Value.ToString("dd/MM/yyyy"),
                                HAN_KDINH = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HAN_KDINH).FirstOrDefault(),
                                NGAY_KDINH = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault(),
                                MA_NUOC = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.MA_NUOC).FirstOrDefault(),
                                SO_CSO = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.SO_CSO).FirstOrDefault(),
                                DONG_DIEN = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.DONG_DIEN).FirstOrDefault(),
                                HANGSO_K = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HANGSO_K).FirstOrDefault() == null ? null : HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HANGSO_K).FirstOrDefault(),
                                TEN_TO = TO.Where(c => c.MA_TO == p.MA_TO).Select(c2 => c2.TEN_TO).FirstOrDefault(),
                                TEN_LO = LO.Where(c => c.MA_LO == p.MA_LO).Select(c2 => c2.TEN_LO).FirstOrDefault(),
                                TEN_TRAM = TRAM.Where(c => c.MA_TRAM == p.MA_TRAM).Select(c2 => c2.TEN_TRAM).FirstOrDefault(),
                                CSUAT_TRAM = TRAM.Where(c => c.MA_TRAM == p.MA_TRAM).Select(c2 => c2.CSUAT_TRAM).FirstOrDefault().ToString(),
                                CAP_DAP = CAPDAP.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.TEN_CAPDA).FirstOrDefault(),
                                TYSO_TU = TUmaxID == null ? null : (TUmaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault() == null ? null : TUmaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault()),
                                NGAY_KDINH_TU = TUKdinh == null ? null : (TUKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault() == null ? null : TUKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault().Value.ToString("dd/MM/yyyy")),
                                TYSO_TI = TImaxID == null ? null : (TImaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault() == null ? null : TImaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault()),
                                NGAY_KDINH_TI = TIKdinh == null ? null : (TIKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault() == null ? null : TIKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault().Value.ToString("dd/MM/yyyy"))

                            }).ToList();


                if (joi7.Count > 0)
                {
                    DataTable dt = Utility.LINQToDataTable(joi7);
                    dt.TableName = "KQ";
                    DataSet ds = new DataSet();
                    ds.Tables.Add(dt);
                    return ds;
                }
                return null;


            }
            catch (Exception ex)
            {
                if (ex.Message.ToString().Contains("ORA-01795"))
                {
                    strErr = "Số điểm đo của sổ lớn hơn 1000, không lấy được dữ liệu !";
                }
                else
                {
                    strErr = "Không lấy được dữ liệu \n" + ex.ToString();
                }
                return null;
            }
        }

        //Lấy thông tin tờ ghi chỉ số công tơ điện tử  - mẫu chung NPC
        public DataSet TogcsNPC_Dtu(Int16 i16NamHD, Int16 i16ThangHD, Int16 i16Ky, string strMa_dviqly, string strMa_sogcs, string strMa_khang, string strLoaiCto, ref string strErr)
        {
            try
            {
                var qddosogcs = (from p in CMIS2.DB.TT_DDO_SOGCS
                                 where p.MA_DVIQLY == strMa_dviqly
                                 && p.MA_SOGCS == strMa_sogcs
                                 //&& p.NGAY_HLUC == CMIS2.DB.TT_DDO_SOGCS.Where(c=> c.MA_DDO == p.MA_DDO).Max(c2=> c2.NGAY_HLUC)
                                 select new
                                 {
                                     p.MA_DVIQLY, // = pgroup.Key.MA_DVIQLY,
                                     p.MA_DDO,  // = pgroup.Key.MA_DDO,
                                     p.MA_SOGCS,  // = pgroup.Key.MA_SOGCS,
                                     p.STT,
                                     p.NGAY_HLUC,
                                     p.ID_QHE
                                 }).ToList();
                if (qddosogcs.Count < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                string[] ArrDDO = qddosogcs.Select(c => c.MA_DDO).Distinct().ToArray();

                var DDOinTT_DDO_SOGCS = (from p in CMIS2.DB.TT_DDO_SOGCS
                                         where p.MA_DVIQLY == strMa_dviqly
                                         && ArrDDO.Contains(p.MA_DDO)
                                         select p).ToList();

                var DDOMaxHL = (DDOinTT_DDO_SOGCS.Where(c => c.NGAY_HLUC == DDOinTT_DDO_SOGCS.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC))).ToList();

                //danh sach diem do hien tai thuoc so                               
                var DDDOSOGCS = (from p in DDOMaxHL
                                 where p.MA_SOGCS == strMa_sogcs
                                 select p).ToList();

                string[] ArrDDOSOGCS = DDDOSOGCS.Select(c => c.MA_DDO).Distinct().ToArray();

                List<TT_CHISO> GCS1 = new List<TT_CHISO>();

                // Lấy ra những điểm đo còn treo công tơ và treo công tơ điện tử
                if (strLoaiCto == "DtuDN")
                {
                    GCS1 = LayTTin_ChiSo_Dtu(strMa_dviqly, ArrDDOSOGCS);
                }
                else
                {
                    return null;
                }

                // Mảng diem do hien tai thuoc so và là điểm đo treo công tơ điện tử
                string[] ArrDDOSOGCS_Co = GCS1.Select(c => c.MA_DDO).Distinct().ToArray();



                //danh sach diem do hien tai thuoc so và treo công tơ điện tử
                var DDOSOGCSfin = (from p in DDDOSOGCS
                                   where p.MA_SOGCS == strMa_sogcs
                                   && ArrDDOSOGCS_Co.Contains(p.MA_DDO)
                                   select p).ToList();




                string[] ArrMADDO = DDOSOGCSfin.Select(c => c.MA_DDO).Distinct().ToArray();

                if (ArrMADDO.Count() < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                //var nl = ArrMADDO.AsEnumerable();

                var DIEMDO = (from p in CMIS2.DB.TT_DIEM_DO
                              where p.MA_DVIQLY == strMa_dviqly
                              && ArrMADDO.Contains(p.MA_DDO)
                              select new
                              {
                                  p.MA_DVIQLY,
                                  p.MA_DDO,
                                  MA_CAPDA = "0" + p.MA_CAPDA,
                                  p.ID_DIA_CHINH,
                                  p.CSUAT,
                                  p.SO_PHA,
                                  p.LAN_CAPNHAT,
                                  p.THAO_TACCDL,
                                  p.NGAY_HLUC,
                                  p.MO_TA,
                                  p.TRANG_THAI,
                                  p.TTRANG_TREOTHAO,
                                  p.TEN_DDO
                              }).ToList();

                if (DIEMDO.Count() < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                var DIEMDOMaxHL1 = (DIEMDO.Where(c => c.NGAY_HLUC == DIEMDO.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC) && c.TRANG_THAI == 1)).ToList();

                var DIEMDOMaxHL = (DIEMDOMaxHL1.Where(c => c.LAN_CAPNHAT == DIEMDOMaxHL1.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.LAN_CAPNHAT))).ToList();
                if (DIEMDOMaxHL.Count() < 1) { strErr = "Không lấy được danh sách điểm đo"; return null; }

                // Lấy cấp Điện áp của điểm đo
                var CAPDAP = (from p in DIEMDOMaxHL
                              join m in CMIS2.DB.D_CAP_DAP
                              on new { p.MA_CAPDA } equals new { m.MA_CAPDA }
                              select new
                              {
                                  p.MA_DDO,
                                  m.TEN_CAPDA
                              }).ToList();



                var VTDDO = (from p in CMIS2.DB.TT_VITRI_DDO
                             where p.MA_DVIQLY == strMa_dviqly
                             && ArrMADDO.Contains(p.MA_DDO)
                             select p).ToList();

                var VTDDOMaxHL = (VTDDO.Where(c => c.NGAY_HLUC == VTDDO.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC))).ToList();
                if (VTDDOMaxHL.Count() < 1) { strErr = "Không lấy được vị trí điểm đo"; return null; }

                string[] ArrTRAM = VTDDOMaxHL.Select(c => c.MA_TRAM).Distinct().ToArray();
                string[] ArrLO = VTDDOMaxHL.Select(c => c.MA_LO).Distinct().ToArray();
                string[] ArrTO = VTDDOMaxHL.Select(c => c.MA_TO).Distinct().ToArray();

                var TRAM = (from p in CMIS2.DB.D_TRAM
                            where p.MA_DVIQLY == strMa_dviqly
                            && ArrTRAM.Contains(p.MA_TRAM)
                            select p).ToList();
                if (TRAM.Count() < 1) { strErr = "Không lấy được danh sách trạm"; }

                var LO = (from p in CMIS2.DB.D_LO
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrLO.Contains(p.MA_LO)
                          select p).ToList();
                if (LO.Count() < 1) { strErr = "Không lấy được danh sách lộ"; }

                var TO = (from p in CMIS2.DB.D_TO
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrTO.Contains(p.MA_TO)
                          select p).ToList();
                if (TO.Count() < 1) { strErr = "Không lấy được danh sách tổ"; }

                var DSOGCS = (from p in CMIS2.DB.D_SOGCS
                              where p.MA_DVIQLY == strMa_dviqly
                              && p.MA_SOGCS == strMa_sogcs
                              //&& p.TINH_TRANG == 1
                              select p).ToList();
                if (DSOGCS.Count < 1) { strErr = "Không lấy được D_SOGCS "; }

                var joi1 = from p in DDOSOGCSfin.ToList()
                           join m in DIEMDOMaxHL.ToList()
                           on new { p.MA_DDO } equals new { m.MA_DDO }
                           select new
                           {
                               p.MA_DDO,
                               p.MA_DVIQLY,
                               p.MA_SOGCS,
                               p.STT,
                               m.SO_PHA,
                               m.CSUAT,
                               m.TEN_DDO
                           };

                //string[] ArrMAKHANG = joi1.Select(c => c.MA_KHANG).Distinct().ToArray();
                //if (ArrMAKHANG.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //var KHACHHANG = (from p in CMIS2.DB.HDG_KHACH_HANG
                //                 where p.MA_DVIQLY == strMa_dviqly
                //                 && ArrMAKHANG.Contains(p.MA_KHANG)
                //                 select p).ToList();
                //if (KHACHHANG.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //var KHACHHANGMaxHL = (KHACHHANG.Where(c => c.NGAY_HLUC == KHACHHANG.Where(c2 => c2.MA_KHANG == c.MA_KHANG).Max(c3 => c3.NGAY_HLUC) && c.TRANG_THAI == 1)).ToList();
                //if (KHACHHANGMaxHL.Count() < 1) { strErr = "Không lấy được danh sách khách hàng"; return null; }

                //long[] ArrIDHDONG = KHACHHANGMaxHL.Select(c => c.ID_HDONG).ToArray();

                //var HOPDONG = (from p in CMIS2.DB.HDG_HOP_DONG
                //               where p.MA_DVIQLY == strMa_dviqly
                //               && ArrIDHDONG.Contains(p.ID_HDONG)
                //               select p).ToList();

                //var HOPDONGMaxHL = (HOPDONG.Where(c => c.NGAY_HLUC == HOPDONG.Where(a => a.ID_HDONG == c.ID_HDONG).Max(s => s.NGAY_HLUC))).ToList();
                //if (HOPDONGMaxHL.Count() < 1) { strErr = "Không lấy được thông tin hợp đồng"; return null; }

                var joi2 = (from p in joi1
                            //join m in KHACHHANGMaxHL
                            //on new { p.MA_KHANG } equals new { m.MA_KHANG }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.SO_PHA,
                                p.CSUAT,
                                p.TEN_DDO
                            }).ToList();

                var joi3 = (from p in joi2
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.SO_PHA,
                                p.CSUAT,
                                p.TEN_DDO
                            }).ToList();


                List<TT_CHISO> GCS = new List<TT_CHISO>();

                if (strLoaiCto == "DtuDN")
                {
                    GCS = LayTTin_ChiSo_Dtu(strMa_dviqly, ArrMADDO);
                }
                else
                {
                    return null;
                }

                if (GCS.Count() < 1) { strErr = "Không lấy được chỉ số"; return null; }

                // Lấy dòng max ID_CHISO của từng điểm đo -> lấy tháng năm lớn nhất của mã điểm đo trong chỉ số
                var gcsMaxIDchiso = (GCS.Where(c => c.ID_CHISO == GCS.Where(c1 => c1.MA_DDO == c.MA_DDO).Max(c2 => c2.ID_CHISO))).ToList();

                //Lấy tháng năm lớn nhất của mã điểm đo trong chỉ số
                var maxThangNam = (from p in gcsMaxIDchiso
                                   select new
                                   {
                                       p.MA_DDO,
                                       p.THANG,
                                       p.NAM
                                   }).ToList();

                // Lấy những dòng chỉ số có tháng năm bằng tháng năm lớn nhất(kỳ mới nhất), 
                // những BCS có chỉ số nhưng ko phải kỳ mới nhất -> không lấy
                var GCSKyMax = from p in GCS
                               join m in maxThangNam
                               on new { p.MA_DDO, p.THANG, p.NAM } equals new { m.MA_DDO, m.THANG, m.NAM }
                               select new
                               {
                                   p.MA_DVIQLY,
                                   p.ID_CHISO,
                                   p.ID_BCS,
                                   p.MA_DDO,
                                   p.MA_DDO_LK,
                                   p.BCS,
                                   p.HS_NHAN,
                                   p.MA_CTO,
                                   p.SO_CTO,
                                   p.KY,
                                   p.THANG,
                                   p.NAM,
                                   p.CHISO_CU,
                                   p.CHISO_MOI,
                                   p.SAN_LUONG,
                                   p.SLUONG_TTIEP,
                                   p.SLUONG_TRPHU,
                                   p.LOAI_CHISO,
                                   p.MA_TTCTO,
                                   p.TRANG_THAI,
                                   p.NGAY_DKY,
                                   p.NGAY_CKY,
                                   p.GIO_BDONG,
                                   p.SLUONG_1,
                                   p.SLUONG_2,
                                   p.SLUONG_3,
                                   p.MA_CNANG
                               };

                var TT_QHEDDODVI = (from p in CMIS2.DB.TT_QHEDDODVI
                                    where ArrMADDO.Contains(p.MA_DDO)
                                    select p).ToList();

                var TT_QHEDDODVIMaxHL = (TT_QHEDDODVI.Where(c => c.NGAY_HLUC == TT_QHEDDODVI.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.NGAY_HLUC) && c.TRANG_THAI == 1)).ToList();


                var GCS_AllinOne = (from p in DDOSOGCSfin
                                    where p.MA_SOGCS == strMa_sogcs
                                    select new
                                    {
                                        p.MA_DDO,
                                        CHISO_MOI_SG_NHAN = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "N" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()),
                                        CHISO_CU_SG_NHAN = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "N" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_CU).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_CU).FirstOrDefault().ToString()),
                                        CHISO_MOI_VC_NHAN = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "N" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()),
                                        CHISO_CU_VC_NHAN = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "N" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_CU).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_CU).FirstOrDefault().ToString()),
                                        CHISO_MOI_SG_GIAO = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "G" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()),
                                        CHISO_CU_SG_GIAO = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "G" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SN").Select(a => a.CHISO_CU).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "SG").Select(a => a.CHISO_CU).FirstOrDefault().ToString()),
                                        CHISO_MOI_VC_GIAO = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "G" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_MOI).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_MOI).FirstOrDefault().ToString()),
                                        CHISO_CU_VC_GIAO = TT_QHEDDODVIMaxHL.Where(c => c.MA_DDO == p.MA_DDO).Select(c1 => c1.CHIEUGNHAN).FirstOrDefault().ToString() == "G" ? (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VN").Select(a => a.CHISO_CU).FirstOrDefault().ToString()) : (GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_CU).FirstOrDefault() == null ? null : GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO && c.BCS == "VC").Select(a => a.CHISO_CU).FirstOrDefault().ToString()),
                                        LOAI_CHISO = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.LOAI_CHISO).FirstOrDefault(),
                                        KY = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.KY).FirstOrDefault(),
                                        THANG = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.THANG).FirstOrDefault(),
                                        NAM = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.NAM).FirstOrDefault(),
                                        HS_NHAN = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.HS_NHAN).FirstOrDefault(),
                                        MA_CTO = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.MA_CTO).FirstOrDefault(),
                                        SO_CTO = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.SO_CTO).FirstOrDefault(),
                                        MA_CNANG = GCSKyMax.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.MA_CNANG).FirstOrDefault()
                                    }).ToList();

                var joi4 = (from p in joi3
                            join m in GCS_AllinOne //GCS
                            on new { p.MA_DDO } equals new { m.MA_DDO }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.TEN_DDO,
                                p.SO_PHA,
                                p.CSUAT,
                                m.KY,
                                m.THANG,
                                m.NAM,
                                m.CHISO_MOI_SG_NHAN,
                                m.CHISO_CU_SG_NHAN,
                                m.CHISO_MOI_VC_NHAN,
                                m.CHISO_CU_VC_NHAN,
                                m.CHISO_MOI_SG_GIAO,
                                m.CHISO_CU_SG_GIAO,
                                m.CHISO_MOI_VC_GIAO,
                                m.CHISO_CU_VC_GIAO,
                                m.LOAI_CHISO,
                                m.HS_NHAN,
                                m.MA_CTO,
                                m.SO_CTO,
                                m.MA_CNANG
                            }).ToList();


                string[] ArrMACTO = GCS.Select(c => c.MA_CTO).Distinct().ToArray();

                var CTO = (from p in CMIS2.DB.DD_HOSO_CTO
                           where p.MA_DVIQLY == strMa_dviqly
                           && ArrMACTO.Contains(p.MA_CTO)
                           select p).ToList();
                if (CTO.Count() < 1) { strErr = "Không lấy được thông tin công tơ"; return null; }

                string[] CLOAI = CTO.Select(c => c.MA_CLOAI).Distinct().ToArray();


                var D_CLOAI_CTO = (from p in CMIS2.DB.D_CLOAI_CTO
                                   where CLOAI.Contains(p.MA_CLOAI)
                                   select new { p.MA_CLOAI, p.SO_PHA, p.MA_NUOC, p.SO_CSO, p.DONG_DIEN, p.HANGSO_K }).ToList();

                var CLOAICTO = (from p in CTO
                                select new
                                {
                                    p.MA_DVIQLY,
                                    p.MA_CTO,
                                    SO_PHA = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.SO_PHA).FirstOrDefault(),
                                    MA_NUOC = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.MA_NUOC).FirstOrDefault(),
                                    SO_CSO = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.SO_CSO).FirstOrDefault(),
                                    DONG_DIEN = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.DONG_DIEN).FirstOrDefault(),
                                    HANGSO_K = D_CLOAI_CTO.Where(c => c.MA_CLOAI == p.MA_CLOAI).Select(c2 => c2.HANGSO_K).FirstOrDefault()
                                }).ToList();

                var KDINH = (from p in CMIS2.DB.DD_KDINH_CTO
                             where p.MA_DVIQLY == strMa_dviqly
                             && ArrMACTO.Contains(p.MA_CTO)
                             select p).ToList();

                var BDONGHTAI_CTO = (from p in CMIS2.DB.DD_BDONG_HTAI
                                     where p.MA_DVIQLY == strMa_dviqly
                                     && ArrMACTO.Contains(p.MA_TBI)
                                     select new
                                     {
                                         MA_CTO = p.MA_TBI,
                                         p.NGAY_BDONG
                                     }).ToList();


                var KDINHMaxHL = (KDINH.Where(c => c.ID_BBAN_KDINH == KDINH.Where(c2 => c2.MA_CTO == c.MA_CTO).Max(c3 => c3.ID_BBAN_KDINH))).ToList();

                // lay han kiem dinh
                var KDINHMaxHLjoiCLOAICTO = (from p in KDINHMaxHL
                                             join m in CLOAICTO
                                             on new { p.MA_CTO } equals new { m.MA_CTO }
                                             select new
                                             {
                                                 p.MA_CTO,
                                                 m.SO_PHA,
                                                 m.MA_NUOC,
                                                 m.SO_CSO,
                                                 m.DONG_DIEN,
                                                 m.HANGSO_K,
                                                 NGAY_KDINH = p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.ToString("dd/MM/yyyy"),
                                                 HAN_KDINH = m.SO_PHA.ToString() == "1" ? (p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.AddYears(5).ToString("dd/MM/yyyy")) : (p.NGAY_KDINH == null ? null : p.NGAY_KDINH.Value.AddYears(2).ToString("dd/MM/yyyy"))
                                             }).ToList();

                var HANKDINH = (from p in KDINHMaxHLjoiCLOAICTO
                                join m in BDONGHTAI_CTO
                                on new { p.MA_CTO } equals new { m.MA_CTO }
                                select new
                                {
                                    p.MA_CTO,
                                    p.SO_PHA,
                                    p.MA_NUOC,
                                    p.SO_CSO,
                                    p.DONG_DIEN,
                                    HANGSO_K = p.HANGSO_K,
                                    p.NGAY_KDINH,
                                    p.HAN_KDINH,
                                    NGAY_BDONG = m.NGAY_BDONG.Date.ToString("dd/MM/yyyy")
                                }).ToList();

                // lấy TU trong DD_BDONG_HTAI
                var TU = (from p in CMIS2.DB.DD_BDONG_TU
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrMADDO.Contains(p.MA_DDO)
                          select p).ToList();

                var TUmaxID = (TU.Where(c => c.ID_BBAN == TU.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.ID_BBAN) && c.MA_BDONG == "B")).ToList();

                var TUKdinh = (from p in TUmaxID
                               join m in CMIS2.DB.DD_KDINH_TU
                              on new { p.MA_DVIQLY, p.MA_TU } equals new { m.MA_DVIQLY, m.MA_TU }
                               select new
                               {
                                   p.MA_DDO,
                                   p.MA_TU,
                                   m.NGAY_KDINH
                               }).ToList();

                // Không đúng
                //var TUKdinh = (from p in CMIS2.DB.DD_KDINH_TU
                //               join m in TUmaxID
                //              on new { p.MA_DVIQLY, p.MA_TU } equals new { m.MA_DVIQLY, m.MA_TU }
                //               select new
                //               {
                //                   m.MA_DDO,
                //                   m.MA_TU,
                //                   p.NGAY_KDINH
                //               }).ToList();


                // lấy TI trong DD_BDONG_HTAI
                var TI = (from p in CMIS2.DB.DD_BDONG_TI
                          where p.MA_DVIQLY == strMa_dviqly
                          && ArrMADDO.Contains(p.MA_DDO)
                          select p).ToList();

                var TImaxID = (TI.Where(c => c.ID_BBAN == TI.Where(c2 => c2.MA_DDO == c.MA_DDO).Max(c3 => c3.ID_BBAN) && c.MA_BDONG == "B")).ToList();

                var TIKdinh = (from p in TImaxID
                               join m in CMIS2.DB.DD_KDINH_TI
                              on new { p.MA_DVIQLY, p.MA_TI } equals new { m.MA_DVIQLY, m.MA_TI }
                               select new
                               {
                                   p.MA_DDO,
                                   p.MA_TI,
                                   m.NGAY_KDINH
                               }).ToList();


                var joi5 = (from p in joi4
                            join m in VTDDOMaxHL
                            on new { p.MA_DDO } equals new { m.MA_DDO }
                            select new
                            {
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                p.TEN_DDO,
                                p.KY,
                                p.THANG,
                                p.NAM,
                                p.CHISO_MOI_SG_NHAN,
                                p.CHISO_CU_SG_NHAN,
                                p.CHISO_MOI_VC_NHAN,
                                p.CHISO_CU_VC_NHAN,
                                p.CHISO_MOI_SG_GIAO,
                                p.CHISO_CU_SG_GIAO,
                                p.CHISO_MOI_VC_GIAO,
                                p.CHISO_CU_VC_GIAO,
                                p.LOAI_CHISO,
                                p.HS_NHAN,
                                p.MA_CTO,
                                p.SO_CTO,
                                p.SO_PHA,
                                p.CSUAT,
                                p.MA_CNANG,
                                m.MA_LO,
                                m.MA_TO,
                                m.MA_TRAM,
                            }).ToList();



                var joi7 = (from p in joi5
                            join m in CTO
                            on new { p.MA_DVIQLY, p.MA_CTO } equals new { m.MA_DVIQLY, m.MA_CTO }
                            orderby p.STT
                            select new
                            {
                                CHON = false,
                                p.MA_DDO,
                                p.MA_DVIQLY,
                                p.MA_SOGCS,
                                p.STT,
                                DIA_CHI = p.TEN_DDO,
                                KY = p.KY.ToString(),
                                THANG = p.THANG.ToString(),
                                NAM = p.NAM.ToString(),
                                p.CHISO_MOI_SG_NHAN,
                                p.CHISO_CU_SG_NHAN,
                                p.CHISO_MOI_VC_NHAN,
                                p.CHISO_CU_VC_NHAN,
                                p.CHISO_MOI_SG_GIAO,
                                p.CHISO_CU_SG_GIAO,
                                p.CHISO_MOI_VC_GIAO,
                                p.CHISO_CU_VC_GIAO,
                                p.LOAI_CHISO,
                                p.HS_NHAN,
                                p.MA_CTO,
                                p.SO_CTO,
                                p.MA_LO,
                                p.MA_TO,
                                p.MA_TRAM,
                                PHA = p.SO_PHA.ToString(),
                                CSUAT_DDO = p.CSUAT.ToString(),
                                HSN = p.HS_NHAN.ToString(),
                                p.MA_CNANG,
                                m.MA_CLOAI,
                                m.NAM_SX,
                                m.LOAI_SOHUU,
                                NGAY_BDONG = m.NGAY_BDONG == null ? null : m.NGAY_BDONG.Value.ToString("dd/MM/yyyy"),
                                HAN_KDINH = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HAN_KDINH).FirstOrDefault(),
                                NGAY_KDINH = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault(),
                                MA_NUOC = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.MA_NUOC).FirstOrDefault(),
                                SO_CSO = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.SO_CSO).FirstOrDefault(),
                                DONG_DIEN = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.DONG_DIEN).FirstOrDefault(),
                                HANGSO_K = HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HANGSO_K).FirstOrDefault() == null ? null : HANKDINH.Where(c => c.MA_CTO == p.MA_CTO).Select(c2 => c2.HANGSO_K).FirstOrDefault(),
                                TEN_TO = TO.Where(c => c.MA_TO == p.MA_TO).Select(c2 => c2.TEN_TO).FirstOrDefault(),
                                TEN_LO = LO.Where(c => c.MA_LO == p.MA_LO).Select(c2 => c2.TEN_LO).FirstOrDefault(),
                                TEN_TRAM = TRAM.Where(c => c.MA_TRAM == p.MA_TRAM).Select(c2 => c2.TEN_TRAM).FirstOrDefault(),
                                CSUAT_TRAM = TRAM.Where(c => c.MA_TRAM == p.MA_TRAM).Select(c2 => c2.CSUAT_TRAM).FirstOrDefault().ToString(),
                                CAP_DAP = CAPDAP.Where(c => c.MA_DDO == p.MA_DDO).Select(a => a.TEN_CAPDA).FirstOrDefault(),
                                TYSO_TU = TUmaxID == null ? null : (TUmaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault() == null ? null : TUmaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault()),
                                NGAY_KDINH_TU = TUKdinh == null ? null : (TUKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault() == null ? null : TUKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault().Value.ToString("dd/MM/yyyy")),
                                TYSO_TI = TImaxID == null ? null : (TImaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault() == null ? null : TImaxID.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.TYSO_DAU).FirstOrDefault()),
                                NGAY_KDINH_TI = TIKdinh == null ? null : (TIKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault() == null ? null : TIKdinh.Where(c => c.MA_DDO == p.MA_DDO).Select(c2 => c2.NGAY_KDINH).FirstOrDefault().Value.ToString("dd/MM/yyyy")),
                                SO_KY = DSOGCS == null ? null : DSOGCS.Where(c => c.MA_SOGCS == strMa_sogcs).Select(a => a.SO_KY).FirstOrDefault().ToString()
                            }).ToList();




                if (joi7.Count > 0)
                {
                    DataTable dt = Utility.LINQToDataTable(joi7);
                    dt.TableName = "KQ";
                    DataSet ds = new DataSet();
                    ds.Tables.Add(dt);
                    return ds;
                }
                return null;


            }
            catch (Exception ex)
            {
                if (ex.Message.ToString().Contains("ORA-01795"))
                {
                    strErr = "Số điểm đo của sổ lớn hơn 1000, không lấy được dữ liệu !";
                }
                else
                {
                    strErr = "Không lấy được dữ liệu \n" + ex.ToString();
                }
                return null;
            }
        }


        // Lấy thông tin chỉ số công tơ cơ KT - mẫu chung NPC
        public List<TT_CHISO> LayTTin_ChiSo_Co(string strMaDVi, string[] ArrDDo)
        {
            try
            {
                CMIS2.ResetDB();
                var lstchiso = ArrDDo.AsEnumerable();
                List<TT_CHISO> CHI_SO = new List<TT_CHISO>();

                while (lstchiso.Count() > 0)
                {
                    var tem = lstchiso.Take(1000);
                    string[] strLoai = { "KT", "VC" };
                    List<TT_CHISO> chiso = (from i in CMIS2.DB.TT_CHISO
                                            where i.MA_DVIQLY == strMaDVi
                                            && tem.Contains(i.MA_DDO)
                                            && strLoai.Contains(i.BCS)
                                            select i).ToList();
                    var ID_CHISO_MAX = chiso.GroupBy(c => new { c.MA_DDO, c.BCS }).Select(k => new { k.Key.MA_DDO, k.Key.BCS, ID_CHISO = k.Max(l => l.ID_CHISO) }).ToList();
                    var KQ = (from i in chiso
                              join j in ID_CHISO_MAX on new { i.MA_DDO, i.ID_CHISO } equals new { j.MA_DDO, j.ID_CHISO }
                              where !i.LOAI_CHISO.Contains("DDN")
                              select i).ToList();
                    CHI_SO = CHI_SO.Union(KQ).ToList();
                    lstchiso = lstchiso.Skip(1000);
                }

                return CHI_SO;
            }
            catch { return null; }
        }

        // Lấy thông tin chỉ số công tơ điện tử  - mẫu chung NPC
        public List<TT_CHISO> LayTTin_ChiSo_Dtu(string strMaDVi, string[] ArrDDo)
        {
            try
            {
                CMIS2.ResetDB();
                var lstchiso = ArrDDo.AsEnumerable();
                List<TT_CHISO> CHI_SO = new List<TT_CHISO>();

                while (lstchiso.Count() > 0)
                {
                    var tem = lstchiso.Take(1000);
                    string[] strLoai = { "BT", "CD", "TD", "VC", "SG", "BN", "CN", "TN", "VN", "SN" };
                    List<TT_CHISO> chiso = (from i in CMIS2.DB.TT_CHISO
                                            where i.MA_DVIQLY == strMaDVi
                                            && tem.Contains(i.MA_DDO)
                                            && strLoai.Contains(i.BCS)
                                            select i).ToList();
                    var ID_CHISO_MAX = chiso.GroupBy(c => new { c.MA_DDO, c.BCS }).Select(k => new { k.Key.MA_DDO, k.Key.BCS, ID_CHISO = k.Max(l => l.ID_CHISO) }).ToList();
                    var KQ = (from i in chiso
                              join j in ID_CHISO_MAX on new { i.MA_DDO, i.ID_CHISO } equals new { j.MA_DDO, j.ID_CHISO }
                              where !i.LOAI_CHISO.Contains("DDN")
                              select i).ToList();
                    CHI_SO = CHI_SO.Union(KQ).ToList();
                    lstchiso = lstchiso.Skip(1000);
                }

                return CHI_SO;
            }
            catch { return null; }
        }

        // Lấy TT_SOGCS
        public DataSet get_TT_SOGCS(string strMa_dviqly, string strMa_sogcs)
        {
            try
            {
                var q = (from p in CMIS2.DB.TT_SOGCS
                         where p.MA_DVIQLY == strMa_dviqly
                         && p.MA_SOGCS == strMa_sogcs
                         select new
                         {
                             p.MA_DVIQLY,
                             p.MA_SOGCS,
                             p.TEN_SOGCS,
                             p.SO_KY,
                             p.TINH_TRANG,
                             p.NGAY_GHI,
                             p.MA_TO,
                             p.NGAY_HLUC,
                             p.NGAY_TAO,
                             p.NGUOI_TAO,
                             p.NGAY_SUA,
                             p.NGUOI_SUA,
                             p.MA_CNANG
                         }).ToList();

                if (q != null && q.Count > 0)
                {
                    DataTable dt = Utility.LINQToDataTable(q);
                    dt.TableName = "TT_SOGCS";
                    DataSet ds = new DataSet();
                    ds.Tables.Add(dt);
                    return ds;
                }

                return null;

            }
            catch
            {
                CMIS2.ResetDB();
                return null;
            }
        }
    }
}
